package org.lc.cmd.plugin.scan;

import org.jline.console.impl.SystemRegistryImpl;
import org.jline.reader.EndOfFileException;
import org.lc.cmd.Cmd;
import org.lc.cmd.ResultHandler;
import org.lc.cmd.exception.CmdException;
import org.lc.cmd.exception.MissParamDataException;
import org.lc.cmd.exception.MissParamException;
import org.lc.cmd.exception.RepeatParamException;
import org.lc.cmd.exception.UnknownCmdException;
import org.lc.cmd.exception.UnknownOptException;
import org.lc.cmd.exception.UnknownParamException;
import org.lc.cmd.util.CmdOutUtil;
import org.lc.cmd.util.StringUtil;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.io.PrintWriter;
import java.io.StringWriter;

@Component
@Order(100)
public class DefaultExceptionHandler implements ResultHandler {
    protected static String fullExpInfo(Throwable e) {
        StringWriter writer = new StringWriter();
        e.printStackTrace(new PrintWriter(writer));
        return writer.getBuffer().toString();
    }

    public String handle(Throwable e) {
        if (e instanceof MissParamDataException) {
            MissParamDataException ex = (MissParamDataException) e;
            return "参数缺少数据：" + StringUtil.noEmptyVal(ex.getOpt(), () -> HelpController.formatCmdParam(ex.getParam()));
        }
        if (e instanceof MissParamException) {
            MissParamException ex = (MissParamException) e;
            return "缺少参数：" + HelpController.formatCmdParam(ex.getParam());
        }
        if (e instanceof RepeatParamException) {
            RepeatParamException ex = (RepeatParamException) e;
            return "参数重复，已有参数数据：" + HelpController.formatCmdParam(ex.getParam());
        }
        if (e instanceof UnknownOptException) {
            UnknownOptException ex = (UnknownOptException) e;
            return "未知参数名：" + ex.getOpt();
        }
        if (e instanceof UnknownParamException) {
            UnknownParamException ex = (UnknownParamException) e;
            return "未知参数值：" + ex.getParam();
        }
        if (e instanceof UnknownCmdException) {
            return "执行命令发生错误:" + e.getMessage() + System.lineSeparator() + fullExpInfo(e);
        }
        if (e instanceof CmdException) {
            return StringUtil.noEmptyVal(e.getMessage(), () -> fullExpInfo(e));
        }
        if (e instanceof SystemRegistryImpl.UnknownCommandException) {
            return "未知命令，" + e.getMessage();
        }
        if (e instanceof EndOfFileException) {
            Cmd.INSTANCE.getBridge().closeClient();
        }
        return null;
    }

    @Override
    public Object handle(Object result, String line) {
        if (!(result instanceof Throwable)) {
            return result;
        }
        String expMsg = handle((Throwable) result);
        if (expMsg != null) {
            CmdOutUtil.writeError(expMsg, false);
            CmdOutUtil.writeln();
            return null;
        }
        return result;
    }
}
